#include  <windows.h>
#include  <GL/gl.h>
#include  <GL/glu.h>

#include <libgraph2D.h>

#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")

TCHAR szWindowName[] = TEXT("Graph2D Test");
HGLRC g_hGLRC;

static void OnCreate(HWND hWnd)
{
	HDC hDC;
	int pfdID;
	BOOL bResult;

	static PIXELFORMATDESCRIPTOR pfd = {
		sizeof (PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL,
		PFD_TYPE_RGBA,
		24,
		0, 0, 0,
		0, 0, 0,
		0, 0,
		0, 0, 0, 0, 0,
		32,
		0,
		0,
		PFD_MAIN_PLANE,
		0,
		0,
		0,
		0
	};

	hDC = GetDC(hWnd);

	pfdID = ChoosePixelFormat(hDC, &pfd);	
	if (pfdID == 0) {
		return;
	}

	bResult = SetPixelFormat(hDC, pfdID, &pfd);
	if (bResult == FALSE) {
		return;
	}

	g_hGLRC = wglCreateContext(hDC);
	if (g_hGLRC == NULL) {
		return;
	}

	ReleaseDC(hWnd, hDC);
}

static void OnPaint(HWND hWnd)
{
	PAINTSTRUCT ps;
	HDC hDC;

	hDC = BeginPaint(hWnd, &ps);

	EndPaint(hWnd, &ps);
}

static void OnDestroy(HWND hWnd)
{
	if(g_hGLRC != NULL)
	{
		wglDeleteContext(g_hGLRC);
	}
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
	switch (nMessage)
	{
	case WM_CREATE:
		OnCreate(hWnd);
		break;
	case WM_PAINT:
		OnPaint(hWnd);
		break;
	case WM_DESTROY:
		OnDestroy(hWnd);
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, nMessage, wParam, lParam);
	}

	return 0;
}


int WINAPI WinMain(HINSTANCE hCurrInstance, HINSTANCE hPrevInstance, LPSTR szArgs, int nWinMode)
{
	HWND hWnd;
	MSG msg;
	WNDCLASSEX wc;

	wc.cbSize = sizeof (WNDCLASSEX);
	wc.hInstance = hCurrInstance;
	wc.lpszClassName = szWindowName;
	wc.lpfnWndProc = WindowProc;
	wc.style = 0;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hIconSm = NULL;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszMenuName = NULL;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	if(!RegisterClassEx(&wc))
	{
		return 0;
	}

	hWnd = CreateWindow(szWindowName,
			szWindowName,
			WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
			CW_USEDEFAULT,
			CW_USEDEFAULT,
			640/*CW_USEDEFAULT*/,
			480/*CW_USEDEFAULT*/,
			NULL,
			NULL,
			hCurrInstance,
			NULL);

	if(!hWnd)
	{
		return 0;
	}

	ShowWindow(hWnd, nWinMode);
	UpdateWindow(hWnd);

	{
		HDC hDC = GetDC(hWnd);

		wglMakeCurrent(hDC, g_hGLRC);
		Graph2D::GraphicDevice::initialize(Graph2D::Vector2(640, 480));

		size_t size = 1024 * 1024 * 10;
		void* buffer = malloc(size);
		Graph2D::Desktop::getInstance().initialize(buffer, size);

		Graph2D::Window<Graph2D::StaticContainer<5>>* window = new Graph2D::Window<Graph2D::StaticContainer<5>>();
		Graph2D::Desktop::getInstance().getScene().set(0, window);
		window->setPosition(16, 32);
		window->setSize(512, 256);
		window->setTextureSize(512, 512);
		window->loadTexture("test.pvr");
		window->open();

		wglMakeCurrent(NULL, NULL);

		while(1)
		{
			if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
			{ 
				if(msg.message == WM_QUIT)
					break;
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			else
			{
				//RenderScene(hDC);
				wglMakeCurrent(hDC, g_hGLRC);
				Graph2D::Desktop::getInstance().updateAndDraw();
				wglMakeCurrent(NULL, NULL);
			} 
		}
		if(hDC) 
		{
			ReleaseDC(hWnd, hDC);
		}

		Graph2D::Desktop::getInstance().finalize();

		Graph2D::GraphicDevice::finalize();
	}

	return msg.wParam;
}
